/*
@(#)SMSUtils   2023-04-23
 
Copyright (c) 2011-2023 杭州湖畔网络技术有限公司 
保留所有权利 
本软件为杭州湖畔网络技术有限公司所有及包含机密信息，须遵守其相关许可证条款进行使用。
Copyright (c) 2011-2023 HUPUN Network Technology CO.,LTD.
All rights reserved.
This software is the confidential and proprietary information of HUPUN
Network Technology CO.,LTD("Confidential Information").  You shall not
disclose such Confidential Information and shall use it only in
accordance with the terms of the license agreement you entered into with HUPUN.
Website：http://www.hupun.com
*/
package org.obp.sms.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import lombok.extern.slf4j.Slf4j;
import org.obp.sms.config.SmsConfig;
import org.obp.sms.consts.SmsTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: Jackey 2023/4/23
 */
@Slf4j
@Component
public class SMSSender implements InitializingBean {

    @Autowired
    private SmsConfig smsConfig;
    @Autowired
    private RestTemplate restTemplate;

    protected IAcsClient acsClient;

    private final String CHINA_CODE = "86";

    @Override
    public void afterPropertiesSet() {
        if (!smsConfig.isEnable()) return;
        DefaultProfile profile = DefaultProfile.getProfile(smsConfig.getRegionId(), smsConfig.getAccessKeyId(), smsConfig.getAccessKeySecret());
        this.acsClient = new DefaultAcsClient(profile);
    }

    /**
     * 发送短信验证码
     *
     * @param nation
     * @param mobile
     * @param code
     * @return
     */
    public boolean sendSmsCode(String nation, String mobile, String code) {

        if (smsConfig.isEnable() && CHINA_CODE.equals(nation)) {

            String template = SmsTemplate.CHINA_TEMPLATE_CODE;
            Map<String, Object> params = new HashMap<>();
            params.put("code", code);
            return this.sendInternalSMS(nation, mobile, template, params);

        } else if (smsConfig.isFORT_ENABLE()) {

            String content = SmsTemplate.FOREIGN_TEMPLATE_CODE.replace("{{code}}", code);
            return this.sendOverseasSMS(nation, mobile, content);
        }

        return false;
    }

    /**
     * 发送短信模版内容
     *
     * @param nation
     * @param mobile
     * @param templateCode
     * @param templateText
     * @param templateParam
     * @return
     */
    public boolean sendSmsText(String nation, String mobile, String templateCode, String templateText, Map<String, Object> templateParam) {

        if (smsConfig.isEnable() && CHINA_CODE.equals(nation)) {

            return this.sendInternalSMS(nation, mobile, templateCode, templateParam);

        } else if (smsConfig.isFORT_ENABLE()) {

            String content = templateText;
            for (String key : templateParam.keySet()) {
                content = content.replace("{{" + key + "}}", String.valueOf(templateParam.get(key)));
            }
            return this.sendOverseasSMS(nation, mobile, content);
        }

        return false;
    }

    private boolean sendInternalSMS(String nation, String mobile, String templateCode, Map<String, Object> templateParam) {
        try {
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(nation + mobile);
            request.setSignName(smsConfig.getSignName());
            request.setTemplateCode(templateCode);
            request.setTemplateParam(JSON.toJSONString(templateParam));
            SendSmsResponse response = acsClient.getAcsResponse(request);

            log.info("发送国内短信: {}, 结果: {}", JSONObject.toJSONString(request), JSONObject.toJSONString(response));
            return response.getCode() != null && response.getCode().equals("OK");

        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return false;
    }

    private boolean sendOverseasSMS(String nation, String mobile, String content) {
        try {
            JSONObject params = new JSONObject();
            params.put("username", smsConfig.getFORT_USERNAME());
            params.put("password", smsConfig.getFORT_PASSWORD());
            params.put("to", "+" + nation + mobile);
            params.put("message", smsConfig.getFORT_SIGN_NAME() + " " + content);

            HttpHeaders headers = new HttpHeaders();
            headers.set(HttpHeaders.CONTENT_TYPE, "application/json");
            HttpEntity<JSONObject> requestEntity = new HttpEntity<>(params, headers);
            String response = restTemplate.postForObject(smsConfig.getFORT_GATEWAY(), requestEntity, String.class);

            log.info("发送国际短信: {}, 结果: {}", JSONObject.toJSONString(params), JSONObject.toJSONString(response));
            return response != null && response.contains("OK");

        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return false;
    }

}